package com.example.testdemo.demos.web.Service.Impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.testdemo.demos.web.Config.Result;
import com.example.testdemo.demos.web.Config.ResultEnum;
import com.example.testdemo.demos.web.Dao.UserDao;
import com.example.testdemo.demos.web.Dao.UserPurviewDao;
import com.example.testdemo.demos.web.Entity.User;
import com.example.testdemo.demos.web.Entity.UserPurview;
import com.example.testdemo.demos.web.Service.QRCodeService;
import com.example.testdemo.demos.web.Service.UserService;
import com.example.testdemo.demos.web.WebSocket.WebSocketServer;
import com.example.testdemo.demos.web.base.RedisDao;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import static com.example.testdemo.demos.web.Tool.JwtUtil.genAccessToken;
import static com.example.testdemo.demos.web.Tool.JwtUtil.parsePayload;
import static com.example.testdemo.demos.web.Tool.UserIdUtil.*;

@Service
public class UserServiceImpl implements UserService {

    @Resource
    private UserDao userDao;
    @Resource
    private UserPurviewDao userPurviewDao;
    @Resource
    private RedisDao redisDao;
    @Resource
    private QRCodeService qrCodeService;

    @Value("${redis.epxtime}")
    private Long epxtime;

    @Autowired
    private WebSocketServer webSocketServer;
    /**
     * 用户注册
     * @param user
     * @return
     */
    @Override
    public Result register(User user){
        Result result =new Result();
        LambdaQueryWrapper<User>lwq =new LambdaQueryWrapper<>();
        lwq.eq(User::getCellPhone,user.getCellPhone());
        List<User> userList =userDao.selectList(lwq);
        if (userList.isEmpty()){
            String userId =generateUserId(user);
            user.setUserId(userId);
            user.setStatus(1);
            String token = genAccessToken(user,"ordinary");
            redisDao.vSet(userId, user,epxtime);
            int res =userDao.insert(user);
            if (res==1){
                UserPurview userPurview =new UserPurview();
                userPurview.setUserId(userId);
                userPurview.setUserPurview("ordinary");
                userPurviewDao.insert(userPurview);
                result.setCode(ResultEnum.SUCCESS.getCode());
                result.setMsg(ResultEnum.SUCCESS.getData());
                result.setData(token);
            }else {
                result.setCode(ResultEnum.BADREQUEST.getCode());
                result.setMsg(ResultEnum.BADREQUEST.getData());
            }
        }else {
            result.setCode(ResultEnum.NODATE.getCode());
            result.setMsg("账号重复！");
        }
        return result;
    }

    /**
     * 登录接口
     * @param user
     * @return
     */
    @Override
    public Result login(User user){
        Result result =new Result();
        LambdaQueryWrapper<User> lwq =new LambdaQueryWrapper<>();
        lwq.eq(User::getCellPhone,user.getCellPhone());
        lwq.eq(User::getPassword,user.getPassword());
        List<User>userList =userDao.selectList(lwq);
        if (userList.isEmpty()){
            result.setCode(ResultEnum.BADREQUEST.getCode());
            result.setMsg("登陆失败！");
        }else {
            UserPurview userPurview=userPurviewDao.selectById(userList.get(0).getUserId());
            String token = genAccessToken(userList.get(0),userPurview.getUserPurview());
            redisDao.vSet(userList.get(0).getUserId(), userList.get(0),epxtime);
            result.setCode(ResultEnum.SUCCESS.getCode());
            result.setMsg("登录成功");
            result.setData(token);
        }
        return result;
    }


    /**
     * 扫码登录
     * @param obj
     * @return
     */
    @Override
    public Result scanCodeLogin(Object obj){
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(obj));
        String fileName =jsonObject.getString("fileName");
        Result result =new Result();
        Claims claims =parsePayload((String) jsonObject.get("scInfo"));
        JSONObject jsonObject1 =JSONObject.parseObject(JSON.toJSONString(claims));
        HashMap<String,String>map =new HashMap<>();
        if (!String.valueOf(jsonObject1.get("jti")).isEmpty()){
            User user =userDao.selectById(String.valueOf(jsonObject1.get("jti")));
            UserPurview userPurview=userPurviewDao.selectById(user.getUserId());
            String token = genAccessToken(user,userPurview.getUserPurview());
            redisDao.vSet(user.getUserId(), user,epxtime);
            map.put("userName", user.getUserName());
            map.put("image", user.getImage());
            map.put("token",token);
            //推送数据
            boolean webSocketCode= webSocketServer.sendMessageToUser(String.valueOf(jsonObject.get("uuid")),token);
            if (webSocketCode){
                result.setCode(ResultEnum.SUCCESS.getCode());
                result.setMsg("登录成功");
                result.setData(map);
            }else {
                result.setCode(ResultEnum.DB_UPDATE_FAILURE.getCode());
                result.setMsg("扫码登录失败！");
                result.setData(token);
            }
        }else {
            result.setCode(ResultEnum.AUTHORIZE_FAILURE.getCode());
            result.setMsg(ResultEnum.AUTHORIZE_FAILURE.getData());
        }
        return result;
    }

    /**
     * 查询用户信息
     * @param userId
     * @return
     */
    @Override
    public Result selUserInfo(String userId){
        Result result =new Result();
        User user =userDao.selectById(userId);
        if (!(user ==null)){
            result.setCode(ResultEnum.SUCCESS.getCode());
            result.setMsg("用户信息查询成功");
            result.setData(user);
        }else {
            result.setCode(ResultEnum.DB_QUERY_FAILURE.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
        }
        return result;
    }

    /**
     * 校验用户登录接口
     * @param userId
     * @return
     */
    @Override
    public Result verifyUser(String userId){
        Result result =new Result();
        User user =userDao.selectById(userId);
        if (!(user ==null)){
            UserPurview userPurview=userPurviewDao.selectById(user.getUserId());
            String token = genAccessToken(user,userPurview.getUserPurview());
            redisDao.vSet(user.getUserId(), user,epxtime);
            result.setCode(ResultEnum.SUCCESS.getCode());
            result.setMsg("用户校验成功");
            result.setData(token);
        }else {
            result.setCode(ResultEnum.DB_QUERY_FAILURE.getCode());
            result.setMsg(ResultEnum.DB_QUERY_FAILURE.getData());
        }
        return result;
    }

    /**
     * 更新用户信息
     */
    @Override
    public Result updateUser(User user){
        Result result =new Result();
        int res=userDao.updateById(user);
        if (res==1){
            result.setCode(ResultEnum.SUCCESS.getCode());
            result.setMsg("更新成功");
        }else {
            result.setCode(ResultEnum.FAILED_VISA_INSPECTION.getCode());
            result.setMsg("更新成功");
        }
        return result;
    }
}
